import React, {useEffect, useState} from 'react';
import echarts from 'echarts';
import VirtualList from 'react-tiny-virtual-list';
import {TARGET_TYPE} from '~/utils/const';
import {getCorePagesPerformance} from '~/service/performance';
import {dateFormat, calcDateRangeStr, parseToWeek} from '../utils';

const Page = ({pathVal, duration, dateRange}) => {
    const {bizTypeName, bizName, path, targetType} = pathVal;
    const containerId = `echarts-${bizName}-${path}-${targetType}`;
    const targetName = TARGET_TYPE.get(targetType);

    // 存储性能
    const [performances, setPerformances] = useState(null);
    // 存储echarts实例
    const [eChartsInstance, setEChartsInstance] = useState(null);

    const generateOption = performances => ({
        legend: {
            bottom: 10,
            left: 'center',
            selected: {
                '均值': false,
                '85th': false,
                '90th': true,
                '95th': true
            }
        },
        grid: {
            top: 20,
            left: 80
        },
        tooltip: {
            trigger: 'axis',
            formatter(param) {
                if (duration === 10) {
                    const htmlChunk =  param.map((item, index) => {
                        let endTime = '';
                        const tempMin = Number(item.name.substring(item.name.length - 2)) + 10;
                        const tempHour = (Number(item.name.substring(0, 2)) + 1)
                            .toString().padStart(2, '0');
                        if (tempMin === 60) {
                            endTime = `${tempHour}: 00`;
                        }
                        else {
                            endTime = `${item.name.substring(0, 2)}:${tempMin}`;
                        }
                        let chunk = `${item.marker}${item.seriesName}: `;
                        if (item.seriesName === '均值') {
                            chunk += `${item.value[1]}<br/>`;
                        }
                        if (item.seriesName === '85th') {
                            chunk += `${item.value[2]}<br/>`;
                        }
                        if (item.seriesName === '90th') {
                            chunk += `${item.value[3]}<br/>`;
                        }
                        if (item.seriesName === '95th') {
                            chunk += `${item.value[4]}<br/>`;
                        }
                        return index === 0
                            ? (
                                `[${item.name}, ${endTime})<br/>${chunk}`
                            ) : `${chunk}`;
                    });
                    return htmlChunk.join('');
                }
                const htmlChunk = param.map((item, index) => {
                    if (item.seriesName === '均值') {
                        return `${item.marker}${item.seriesName}: ${item.value[1]}<br/>`;
                    }
                    if (item.seriesName === '85th') {
                        return `${item.marker}${item.seriesName}: ${item.value[2]}<br/>`;
                    }
                    if (item.seriesName === '90th') {
                        return `${item.marker}${item.seriesName}: ${item.value[3]}<br/>`;
                    }
                    if (item.seriesName === '95th') {
                        return `${item.marker}${item.seriesName}: ${item.value[4]}<br/>`;
                    }
                    return null;

                });
                return `${param[0].name} ${parseToWeek(param[0].name)}<br/>${htmlChunk.join('')}`;
            }
        },
        dataset: {
            source: performances.map(_ =>
                ['datetime', 'targetAvg', 'target85th', 'target90th', 'target95th'].map(key => _[key]))
        },
        xAxis: {
            type: 'category',
        },
        yAxis: {
            type: 'value',
            axisLabel: {
                formatter(val) {
                    if (val > 0) {
                        return `${val}ms`;
                    }
                    return val;
                }
            }
        },
        series: ['均值', '85th', '90th', '95th'].map((key, index) => (
            {
                type: 'line',
                smooth: true,
                encode: {
                    x: 0,
                    y: index + 1,
                },
                name: key
            }
        )),
    });

    // 获取性能数据并初始化折线图
    useEffect(() => {
        const chartsContainer = echarts.init(document.getElementById(containerId));
        setEChartsInstance(chartsContainer);

        if (performances) {
            chartsContainer.setOption(generateOption(performances), true);
        }

        window.addEventListener('resize', chartsContainer.resize);
        return () => {
            window.removeEventListener('resize', chartsContainer.resize);
        };
    }, []);
    // 获取性能数据
    useEffect(() => {
        let isUnmount = false;
        (async () => {
            const [startTime, endTime] = calcDateRangeStr(dateRange);
            const pagePerformance = await getCorePagesPerformance({
                targetType,
                bizTypeName,
                bizName,
                path,
                startTime,
                endTime,
                timeType: duration
            });
            if (!isUnmount) {
                setPerformances(pagePerformance.data.performanceMeasures.map(_ => ({
                    ..._,
                    datetime: dateFormat(_.datetime, duration),
                })));
            }

        })();
        return () => {
            isUnmount = true;
        };
    }, [dateRange, duration]);

    // echarts更新
    useEffect(() => {
        if (performances && eChartsInstance) {
            eChartsInstance.setOption(generateOption(performances), true);
        }
    }, [performances]);

    return (
        <div className="graph-container">
            <div className="panel">
                <div className="graph-title">
                    <span className="target">
                        {targetName}
                    </span>
                    <span className="path" title={path}>
                        {path}
                    </span>
                </div>
                <div className="graph" id={containerId}></div>
            </div>
        </div>
    );
};

export default ({formatPaths, duration, dateRange}) => {
    function renderItem({index, style}) {
        const paths = formatPaths[index];
        const [firstPath, secondPath] = paths;
        return (
            <div key={`${firstPath.bizName}${firstPath.path}${firstPath.targetType}`} style={style}>
                {
                    firstPath.isFirst
                    && (
                        <p className="application-name">
                            {firstPath.bizName}
                        </p>
                    )
                }
                <Page
                    pathVal={firstPath}
                    duration={duration}
                    dateRange={dateRange}
                    index={index}
                />
                {
                    secondPath
                    && (
                        <Page
                            pathVal={secondPath}
                            duration={duration}
                            dateRange={dateRange}
                        />
                    )
                }
            </div>
        );
    }

    function sizeGetter(index) {
        return formatPaths[index][0].isFirst ? 400 : 350;
    }

    return !!formatPaths
        && !!formatPaths.length
        && (
            <VirtualList
                className="graph-list"
                width="100%"
                height={690}
                itemCount={formatPaths.length}
                itemSize={sizeGetter}
                renderItem={renderItem}
                overscanCount={2}
            />
        );
};
